package dse.messages;

import java.util.Random;

import dse.Experiment;
import dse.ExperimentRecorder;
import dse.Node;

/**
 * These are things nodes are trying to do.  Messages are the means by which
 * transactions are accomplished though.
 * 
 * @author Sam
 */
public abstract class Transaction extends MessageSender {
	protected int id;
	protected Node requester;
	
	protected boolean started;
	protected boolean finished;
	protected double startTime;
	
	protected boolean isUpdate;
	protected boolean isPartialUpdate;
	protected static Random random = new Random(123123);
	
	
	public Transaction (int id, Node requester, Experiment experiment) {
		super(experiment);
		
		this.id = id;
		this.requester = requester;
		this.startTime = experiment.currentTime();
		double rd = random.nextDouble();
		//System.out.println(rd);
		isUpdate = (rd<experiment.configuration().getWritingReadingRatio())?true:false;
	}
	
	public Transaction (int id, Node requester, Experiment experiment, double startTime)
	{
		super(experiment);
		
		this.id = id;
		this.requester = requester;
		this.startTime = startTime;
		double rd = random.nextDouble();
		//System.out.println(rd);
		isUpdate = (rd<experiment.configuration().getWritingReadingRatio())?true:false;
		isPartialUpdate = false;
		if(isUpdate)
		{
			double rd2 = random.nextDouble();
			if(rd2<experiment.configuration().getPartialUpdateRatio())
				isPartialUpdate = true;
		}
	}
	
	
	/**
	 * Get the id of the transaction.
	 * 
	 * @return
	 */
	public int id () { return id; } 
	/**
	 * Called by the experiment to see if the transaction is finished and
	 * can be removed from the system.
	 * 
	 * @return
	 */
	public boolean isFinished () {
		return finished;
	}
	/**
	 * The node initiating the transaction.
	 * 
	 * @return
	 */
	public Node primaryNode () {
		return requester;
	}
	/**
	 * Returns the start time of the transaction.
	 * 
	 * @return
	 */
	public double startTime () {
		return startTime;
	}
	
	public boolean isUpdate(){
		return isUpdate;
	}
	/**
	 * This should initate the transaction.  Everything for the transaction 
	 * from this point on should be handled based on message received events.
	 * See the MessageHandler interface for details on that. 
	 * 
	 * @param recorder
	 * @param timeLeft
	 */
	public abstract void start (ExperimentRecorder recorder);
}
